import { marked } from 'marked';
import TurndownService from 'turndown';
import { Document, Packer, Paragraph, TextRun, HeadingLevel, AlignmentType, LevelFormat } from 'docx';

/**
 * 复制工具类 - 使用真正的第三方库
 */
export class CopyUtils {
  constructor(toastFn = console.log) {
    this.toast = toastFn;
    this.turndownService = new TurndownService();
  }

  /**
   * 复制为纯文本 - 使用 turndown 库
   */
  async copyAsText(markdown) {
    try {
      // 先转为 HTML 再转为纯文本，保证质量
      const html = marked(markdown);
      const doc = new DOMParser().parseFromString(html, 'text/html');
      const plainText = doc.body.textContent || '';
      
      await navigator.clipboard.writeText(plainText);
      this.toast("已复制为纯文本", "success");
      return true;
    } catch (error) {
      console.error("复制失败:", error);
      this.toast("复制失败", "error");
      return false;
    }
  }

  /**
   * 复制为 HTML - 使用 marked 库
   */
  async copyAsHtml(markdown) {
    try {
      const html = marked(markdown, {
        breaks: true,
        gfm: true,
        headerIds: false,
        mangle: false
      });
      
      const styledHtml = `
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.2.0/github-markdown-light.min.css">
    <style>
        .markdown-body {
            box-sizing: border-box;
            min-width: 200px;
            max-width: 980px;
            margin: 0 auto;
            padding: 45px;
        }
    </style>
</head>
<body>
    <div class="markdown-body">
        ${html}
    </div>
</body>
</html>`;
      
      const plainText = await this.markdownToPlainText(markdown);
      
      const clipboardItem = new ClipboardItem({
        'text/html': new Blob([styledHtml], { type: 'text/html' }),
        'text/plain': new Blob([plainText], { type: 'text/plain' })
      });
      
      await navigator.clipboard.write([clipboardItem]);
      this.toast("已复制为 HTML（GitHub 样式）", "success");
      return true;
    } catch (error) {
      console.error("复制 HTML 失败:", error);
      return await this.copyAsText(markdown);
    }
  }

  /**
   * 复制为 Word 文档 - 使用 docx 库
   */
  async copyAsOffice(markdown) {
    try {
      const numbering = this.createNumberingConfig();
      const docElements = await this.markdownToDocx(markdown);
      
      const doc = new Document({
        numbering: numbering,
        sections: [{
          properties: {},
          children: docElements
        }]
      });

      const buffer = await Packer.toBuffer(doc);
      const blob = new Blob([buffer], { 
        type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' 
      });
      
      const plainText = await this.markdownToPlainText(markdown);
      
      const clipboardItem = new ClipboardItem({
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document': blob,
        'text/plain': new Blob([plainText], { type: 'text/plain' })
      });
      
      await navigator.clipboard.write([clipboardItem]);
      this.toast("已复制为 Word 文档", "success");
      return true;
    } catch (error) {
      console.error("Word 文档复制失败:", error);
      // 降级到 HTML
      return await this.copyAsHtml(markdown);
    }
  }

  /**
   * 复制 Markdown 源码
   */
  async copyAsMarkdown(markdown) {
    try {
      await navigator.clipboard.writeText(markdown);
      this.toast("已复制 Markdown 源码", "success");
      return true;
    } catch (error) {
      console.error("复制 Markdown 失败:", error);
      this.toast("复制失败", "error");
      return false;
    }
  }

  /**
   * 创建编号配置
   */
  createNumberingConfig() {
    return {
      config: [
        {
          reference: "ordered-list",
          levels: [
            {
              level: 0,
              format: LevelFormat.DECIMAL,
              text: "%1.",
              alignment: AlignmentType.START,
              style: {
                paragraph: {
                  indent: { left: 360, hanging: 180 }, // 减少缩进：左缩进 360twips, 悬挂缩进 180twips
                  spacing: { after: 120 }
                },
                run: {
                  size: 22, // 11pt
                  font: "Calibri"
                }
              }
            },
            {
              level: 1,
              format: LevelFormat.LOWER_LETTER,
              text: "%2)",
              alignment: AlignmentType.START,
              style: {
                paragraph: {
                  indent: { left: 540, hanging: 180 }, // 减少二级缩进
                  spacing: { after: 120 }
                },
                run: {
                  size: 22,
                  font: "Calibri"
                }
              }
            },
            {
              level: 2,
              format: LevelFormat.LOWER_ROMAN,
              text: "%3)",
              alignment: AlignmentType.START,
              style: {
                paragraph: {
                  indent: { left: 720, hanging: 180 }, // 减少三级缩进
                  spacing: { after: 120 }
                },
                run: {
                  size: 22,
                  font: "Calibri"
                }
              }
            }
          ]
        },
        {
          reference: "bullet-list",
          levels: [
            {
              level: 0,
              format: LevelFormat.BULLET,
              text: "•",
              alignment: AlignmentType.START,
              style: {
                paragraph: {
                  indent: { left: 360, hanging: 180 }, // 减少无序列表缩进
                  spacing: { after: 120 }
                },
                run: {
                  size: 22,
                  font: "Calibri"
                }
              }
            },
            {
              level: 1,
              format: LevelFormat.BULLET,
              text: "◦",
              alignment: AlignmentType.START,
              style: {
                paragraph: {
                  indent: { left: 540, hanging: 180 },
                  spacing: { after: 120 }
                },
                run: {
                  size: 22,
                  font: "Calibri"
                }
              }
            },
            {
              level: 2,
              format: LevelFormat.BULLET,
              text: "▪",
              alignment: AlignmentType.START,
              style: {
                paragraph: {
                  indent: { left: 720, hanging: 180 },
                  spacing: { after: 120 }
                },
                run: {
                  size: 22,
                  font: "Calibri"
                }
              }
            }
          ]
        }
      ]
    };
  }

  /**
   * 使用 docx 库转换 Markdown 为 Word 元素 - 优化版
   */
  async markdownToDocx(markdown) {
    const lines = markdown.split('\n');
    const elements = [];
    let currentListType = null;
    let listCounter = 0;
    
    for (let i = 0; i < lines.length; i++) {
      const line = lines[i];
      
      if (line.startsWith('# ')) {
        currentListType = null;
        elements.push(new Paragraph({
          text: line.substring(2),
          heading: HeadingLevel.HEADING_1,
          spacing: { after: 240, before: 240 }
        }));
      } else if (line.startsWith('## ')) {
        currentListType = null;
        elements.push(new Paragraph({
          text: line.substring(3),
          heading: HeadingLevel.HEADING_2,
          spacing: { after: 200, before: 200 }
        }));
      } else if (line.startsWith('### ')) {
        currentListType = null;
        elements.push(new Paragraph({
          text: line.substring(4),
          heading: HeadingLevel.HEADING_3,
          spacing: { after: 160, before: 160 }
        }));
      } else if (line.match(/^\d+\.\s+/)) {
        // 有序列表处理
        const text = line.replace(/^\d+\.\s+/, '');
        const level = this.getListLevel(line);
        
        if (currentListType !== 'ordered') {
          currentListType = 'ordered';
          listCounter = 0;
        }
        
        const runs = this.parseTextRuns(text);
        elements.push(new Paragraph({
          children: runs,
          numbering: {
            reference: "ordered-list",
            level: level
          },
          spacing: { after: 120 }
        }));
      } else if (line.match(/^[\s]*[-*+]\s+/)) {
        // 无序列表处理
        const text = line.replace(/^[\s]*[-*+]\s+/, '');
        const level = this.getListLevel(line);
        
        if (currentListType !== 'bullet') {
          currentListType = 'bullet';
        }
        
        const runs = this.parseTextRuns(text);
        elements.push(new Paragraph({
          children: runs,
          numbering: {
            reference: "bullet-list",
            level: level
          },
          spacing: { after: 120 }
        }));
      } else if (line.trim() !== '') {
        currentListType = null;
        // 处理普通段落
        const runs = this.parseTextRuns(line);
        elements.push(new Paragraph({ 
          children: runs,
          spacing: { after: 160 }
        }));
      } else {
        // 空行处理
        if (currentListType) {
          // 在列表中的空行不重置列表类型
          continue;
        }
        elements.push(new Paragraph({ 
          text: "",
          spacing: { after: 120 }
        }));
      }
    }
    
    return elements;
  }

  /**
   * 获取列表层级
   */
  getListLevel(line) {
    const match = line.match(/^(\s*)/);
    const indentLength = match ? match[1].length : 0;
    
    // 每2个空格或1个tab为一级
    if (indentLength >= 4) return 2;
    if (indentLength >= 2) return 1;
    return 0;
  }

  /**
   * 解析文本格式 - 增强版
   */
  parseTextRuns(text) {
    const runs = [];
    let currentPos = 0;
    
    // 处理粗体和斜体的正则表达式
    const formattingRegex = /(\*\*([^*]+)\*\*)|(\*([^*]+)\*)|(`([^`]+)`)|(__([^_]+)__)|(_([^_]+)_)/g;
    let match;
    
    while ((match = formattingRegex.exec(text)) !== null) {
      // 添加前面的普通文本
      if (match.index > currentPos) {
        runs.push(new TextRun(text.substring(currentPos, match.index)));
      }
      
      // 根据匹配的类型添加格式化文本
      if (match[1]) { // **粗体**
        runs.push(new TextRun({
          text: match[2],
          bold: true
        }));
      } else if (match[3]) { // *斜体*
        runs.push(new TextRun({
          text: match[4],
          italics: true
        }));
      } else if (match[5]) { // `代码`
        runs.push(new TextRun({
          text: match[6],
          font: "Consolas",
          size: 20, // 10pt
          color: "666666"
        }));
      } else if (match[7]) { // __粗体__
        runs.push(new TextRun({
          text: match[8],
          bold: true
        }));
      } else if (match[9]) { // _斜体_
        runs.push(new TextRun({
          text: match[10],
          italics: true
        }));
      }
      
      currentPos = match.index + match[0].length;
    }
    
    // 添加剩余文本
    if (currentPos < text.length) {
      runs.push(new TextRun(text.substring(currentPos)));
    }
    
    return runs.length > 0 ? runs : [new TextRun(text)];
  }

  /**
   * 使用浏览器 API 转换为纯文本
   */
  async markdownToPlainText(markdown) {
    const html = marked(markdown);
    const doc = new DOMParser().parseFromString(html, 'text/html');
    return doc.body.textContent || '';
  }

  /**
   * 创建 Word 兼容的 HTML - 优化列表样式
   */
  createWordCompatibleHtml(content) {
    return `
<html xmlns:o="urn:schemas-microsoft-com:office:office"
      xmlns:w="urn:schemas-microsoft-com:office:word"
      xmlns="http://www.w3.org/TR/REC-html40">
<head>
    <meta charset="utf-8">
    <meta name=ProgId content=Word.Document>
    <meta name=Generator content="Microsoft Word 15">
    <style>
        body {
            font-family: "Calibri", "Microsoft YaHei", sans-serif;
            font-size: 11.0pt;
            line-height: 1.15;
            color: #000000;
            background: white;
            margin: 0;
            padding: 20pt;
        }
        
        h1 {
            font-size: 18.0pt;
            font-weight: bold;
            color: #2E75B5;
            margin-top: 12.0pt;
            margin-bottom: 6.0pt;
        }
        
        h2 {
            font-size: 16.0pt;
            font-weight: bold;
            color: #2E75B5;
            margin-top: 10.0pt;
            margin-bottom: 6.0pt;
        }
        
        h3 {
            font-size: 14.0pt;
            font-weight: bold;
            color: #1F4E79;
            margin-top: 10.0pt;
            margin-bottom: 6.0pt;
        }
        
        p {
            margin-top: 0pt;
            margin-bottom: 8.0pt;
            line-height: 1.15;
        }
        
        /* 优化的列表样式 - 减少左边距 */
        ol {
            margin: 0;
            padding: 0;
            list-style: none;
            counter-reset: list-counter;
        }
        
        ol > li {
            counter-increment: list-counter;
            margin: 0 0 6pt 0;
            padding: 0 0 0 20pt; /* 减少左内边距 */
            text-indent: -12pt; /* 减少悬挂缩进 */
            position: relative;
        }
        
        ol > li:before {
            content: counter(list-counter) ".;
            position: absolute;
            left: 0;
            top: 0;
            width: 12pt; /* 减少数字区域宽度 */
            text-align: left;
            font-weight: normal;
            color: #000000;
        }
        
        ul {
            margin: 0;
            padding: 0;
            list-style: none;
        }
        
        ul > li {
            margin: 0 0 6pt 0;
            padding: 0 0 0 20pt; /* 减少左内边距 */
            text-indent: -12pt; /* 减少悬挂缩进 */
            position: relative;
        }
        
        ul > li:before {
            content: "•";



            
            position: absolute;
            left: 0;
            top: 0;
            width: 12pt; /* 减少符号区域宽度 */
            text-align: left;
            font-weight: bold;
            color: #000000;
        }
        
        /* 嵌套列表 */
        ol ol > li {
            padding-left: 32pt; /* 减少二级列表缩进 */
            text-indent: -12pt;
        }
        
        ol ol > li:before {
            content: counter(list-counter, lower-alpha) ")";
            left: 20pt;
        }
        
        ul ul > li {
            padding-left: 32pt; /* 减少二级列表缩进 */
            text-indent: -12pt;
        }
        
        ul ul > li:before {
            content: "◦";
            left: 20pt;
        }
        
        blockquote {
            margin: 0 0 8pt 20pt; /* 减少引用左边距 */
            border-left: 3pt solid #CCCCCC;
            padding-left: 12pt;
            font-style: italic;
            color: #666666;
        }
        
        code {
            font-family: "Consolas", "Courier New", monospace;
            font-size: 10.0pt;
            background-color: #F2F2F2;
            border: 1pt solid #CCCCCC;
            padding: 1pt 4pt;
            border-radius: 2pt;
        }
        
        pre {
            font-family: "Consolas", "Courier New", monospace;
            font-size: 10.0pt;
            background-color: #F8F8F8;
            border: 1pt solid #CCCCCC;
            padding: 8pt;
            margin: 0 0 8pt 0;
            border-radius: 3pt;
        }
        
        table {
            border-collapse: collapse;
            width: 100%;
            margin: 0 0 8pt 0;
        }
        
        th, td {
            border: 1pt solid #CCCCCC;
            padding: 4pt 8pt;
            text-align: left;
            vertical-align: top;
        }
        
        th {
            background-color: #F2F2F2;
            font-weight: bold;
        }
    </style>
</head>
<body>
    ${content}
</body>
</html>`;
  }
}

export function createCopyUtils(toastFn) {
  return new CopyUtils(toastFn);
}

export const copyUtils = {
  copyAsText: (markdown, toastFn) => new CopyUtils(toastFn).copyAsText(markdown),
  copyAsHtml: (markdown, toastFn) => new CopyUtils(toastFn).copyAsHtml(markdown),
  copyAsOffice: (markdown, toastFn) => new CopyUtils(toastFn).copyAsOffice(markdown),
  copyAsMarkdown: (markdown, toastFn) => new CopyUtils(toastFn).copyAsMarkdown(markdown),
};